package video_downloader

import (
	"context"
	"fmt"
	"image_demo/internal/constants"
	"io"
	"math/rand"
	"net/http"
	"os"
	"path/filepath"
	"strings"
)

// Downloader 处理视频下载
type Downloader struct {
	httpClient *http.Client
}

// NewDownloader 创建新的视频下载器
func NewDownloader() *Downloader {
	return &Downloader{
		httpClient: createHttpClient(),
	}
}

// 创建带防限流配置的HTTP客户端
func createHttpClient() *http.Client {
	return &http.Client{
		Timeout: constants.HTTPTimeout,
		Transport: &http.Transport{
			MaxIdleConns:        constants.MaxIdleConns,
			IdleConnTimeout:     constants.IdleConnTimeout,
			DisableCompression:  true,
			DisableKeepAlives:   false,
			MaxIdleConnsPerHost: constants.MaxIdleConnsPerHost,
		},
	}
}

// 获取随机User-Agent
func getRandomUserAgent() string {
	return constants.UserAgents[rand.Intn(len(constants.UserAgents))]
}

// DownloadVideo 下载视频文件
func (d *Downloader) DownloadVideo(ctx context.Context, videoURL, outputDir string) error {
	req, err := http.NewRequestWithContext(ctx, "GET", videoURL, nil)
	if err != nil {
		return fmt.Errorf("创建视频请求失败: %v", err)
	}

	// 设置视频下载的请求头
	req.Header.Set(constants.UserAgentHeader, getRandomUserAgent())
	req.Header.Set(constants.AcceptHeader, "*/*") // 视频下载接受所有类型
	req.Header.Set(constants.AcceptLanguageHeader, constants.DefaultAcceptLanguage)
	req.Header.Set(constants.RefererHeader, constants.DefaultReferer)

	resp, err := d.httpClient.Do(req)
	if err != nil {
		return fmt.Errorf("下载视频失败: %v", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != constants.HTTPStatusOK {
		return fmt.Errorf("视频下载失败，状态码: %d", resp.StatusCode)
	}

	// 获取视频文件扩展名
	contentType := resp.Header.Get("Content-Type")
	fileExt := getVideoExtension(contentType, videoURL)

	outputPath := generateOutputPath(videoURL, outputDir, fileExt)

	// 确保输出目录存在
	dir := filepath.Dir(outputPath)
	if err := os.MkdirAll(dir, constants.DirPermission); err != nil {
		return fmt.Errorf("创建目录失败: %v", err)
	}

	// 创建输出文件
	outputFile, err := os.Create(outputPath)
	if err != nil {
		return fmt.Errorf("创建输出文件失败: %v", err)
	}
	defer outputFile.Close()

	// 复制视频数据到文件
	if _, err := io.Copy(outputFile, resp.Body); err != nil {
		return fmt.Errorf("保存视频文件失败: %v", err)
	}

	fmt.Printf("成功下载视频: %s\n", outputPath)
	return nil
}

// getVideoExtension 根据Content-Type和URL获取视频文件扩展名
func getVideoExtension(contentType, videoURL string) string {
	// 优先根据Content-Type判断
	switch contentType {
	case "video/mp4":
		return ".mp4"
	case "video/webm":
		return ".webm"
	case "video/avi":
		return ".avi"
	case "video/mov":
		return ".mov"
	case "video/mkv":
		return ".mkv"
	default:
		// 如果Content-Type未知，从URL中提取扩展名
		ext := filepath.Ext(videoURL)
		if ext != "" {
			return ext
		}
		// 默认使用mp4格式
		return ".mp4"
	}
}

// GenerateOutputPath 生成输出文件路径
func GenerateOutputPath(videoURL, outputDir, fileExt string) string {
	baseName := filepath.Base(videoURL)
	originalExt := filepath.Ext(baseName)
	nameWithoutExt := strings.TrimSuffix(baseName, originalExt)

	// 如果URL中已经有扩展名，使用URL中的扩展名
	if originalExt != "" && originalExt != fileExt {
		// 如果扩展名不同，使用新的扩展名
		return filepath.Join(outputDir, nameWithoutExt+fileExt)
	}

	return filepath.Join(outputDir, baseName)
}

// 内部使用的generateOutputPath函数
func generateOutputPath(videoURL, outputDir, fileExt string) string {
	return GenerateOutputPath(videoURL, outputDir, fileExt)
}
